package com.cmpe.av;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.io.PrintWriter; 

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.MultipartStream;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.cmpe.av.logic.ReportLogic;
import com.cmpe.av.logic.UserLogic;
import com.cmpe.av.model.Comment;
import com.cmpe.av.model.Report;
import com.cmpe.av.model.Subscription;
import com.cmpe.av.model.User;
//import com.oreilly.servlet.MultipartRequest;
/**
 * Servlet implementation class SearchPage
 */
@WebServlet("/ViewPage")
public class ViewPage extends HttpServlet {

	/**
	 * 
	 */
	/*
        private boolean isMultipart;
        private String imagePath = "/home/project6/upload/image/";

        private String tempPath = "/home/project6/upload/temp";


        private int maxFileSize = 50 * 1024 *1024;
        private int maxMemSize = 4 * 1024;
        private File file ;
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ViewPage() {
		super();
		// TODO Auto-generated constructor stub
	}

	protected void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		//       FileItem imageFileItem = null;
		ReportLogic msAccess;
		UserLogic msAccess2;
		Report report = new Report();
		User user = new User();

		Comment comment = new Comment();
		HttpSession session = request.getSession();
		Integer userID = -1;
		if(session.getAttribute("userID") != null)
			userID = (Integer) session.getAttribute("userID");

		if(userID == -1)
			request.setAttribute("isGuest", true);

		System.out.println(userID);
		long reportID=0;
		String comments;
		String description;
		String newTags;
		String status;
		int statusNo;
		int rate;
		boolean subscriptionStatus;
		//user attributes
		int reportRate;
		int wrongReport;
		int score;

		if(request.getParameter("qid")!=null)
			reportID = Long.parseLong(request.getParameter("qid"));
		else{
			reportID = Long.parseLong(request.getParameter("id"));
		}
		/*      
                        isMultipart = ServletFileUpload.isMultipartContent(request);
                        java.io.PrintWriter out = response.getWriter( );
                        if( !isMultipart ){
                                return;
                        }
                        DiskFileItemFactory factory = new DiskFileItemFactory();
                        // maximum size that will be stored in memory
                        factory.setSizeThreshold(maxMemSize);
                        // Location to save data that is larger than maxMemSize.
                        //            factory.setRepository(new File("/home/project6/upload/temp"));
                        //              factory.setRepository(new File(tempPath));
                        factory.setRepository(new File(tempPath));

                        // Create a new file upload handler
                        ServletFileUpload upload = new ServletFileUpload(factory);
                        // maximum file size to be uploaded.
                        upload.setSizeMax( maxFileSize );

		 */
		try{
			msAccess = new ReportLogic(); 
			msAccess2 = new UserLogic(); 
			int imageNum=msAccess.getImageNum(reportID);
			/*  
                    int imageNum=msAccess.getImageNum(reportID);
                    int tempImageNum=imageNum;

                                try{ 
                                        // Parse the request to get file items.
                                        List<FileItem> fileItems = upload.parseRequest(request);
                                        // Process the uploaded file items
                                        Iterator<FileItem> i = fileItems.iterator();

                                        while ( i.hasNext () ) 
                                        {
                                                FileItem fi = i.next();
                                                if ( !fi.isFormField ())        
                                                {
                                                        //Check format
                                                        if( fi.getContentType().contains(fi.getFieldName()) ){
                                                                // Get the uploaded file parameters
                                                                String contentType = fi.getContentType();
                                                                long sizeInBytes = fi.getSize();
                                                                // Write the file
                                                                if(contentType.contains("image")){
                                                                        imageFileItem = fi;
                                                                        imageNum++;
                                                                }

                                                        }
                                                }else{ 

                                                }
                                        }
                                }catch(Exception ex) {
                                        System.out.println(ex);
                                }
			 */
			report = msAccess.viewReport(reportID);
			rate = report.getRate();

			subscriptionStatus = msAccess.getSubscriptionStatus(userID,reportID);
			user = msAccess2.getUser(report.getUser_id());
			List<String> tagsShow = msAccess.getTagsInReport(reportID);
			List<Comment> commentList = msAccess.getComments(reportID);


			request.setAttribute("imageNum", imageNum);
			request.setAttribute("valid", true);
			request.setAttribute("report", report);
			request.setAttribute("reportID", reportID);
			request.setAttribute("comments", commentList);
			request.setAttribute("rate", report.getRate());
			request.setAttribute("user", user);
			request.setAttribute("tagsShow", tagsShow);
			request.setAttribute("obsName", msAccess.getObstacleName(report.getObstacle_id()));
			request.setAttribute("status", msAccess.getStatusName(report.getStatus()));
			request.setAttribute("subsStatus", subscriptionStatus);

			if (request.getParameter("button")!=null){       


				if(request.getParameter("button").equals("Login")){

					String userName = request.getParameter("name");
					String passWord = request.getParameter("password");
					String strErrMsg = null;
					session = request.getSession();
					userID = -1;
					// response.
					try {
						msAccess2 = new UserLogic();

						userID = msAccess2.getUserID(userName, passWord);
						if (userID != -1) {
							session.setAttribute("userName", userName);
							session.setAttribute("loggedin", true);
							session.setAttribute("userID", userID);

							response.setHeader("Cache-Control","no-cache"); 
							response.setHeader("Pragma","no-cache"); 
							response.setDateHeader ("Expires", 0); 
							response.setHeader("Cache-Control", "no-store");
							request.setAttribute("isGuest", false);
							request.getRequestDispatcher("/viewReport.jsp?qid=" + reportID).forward(request, response);
						} else {
							request.setAttribute("invalidLogin", true);
							request.getRequestDispatcher("/viewReport.jsp?qid=" + reportID).forward(request, response);
						}
					} 

					catch (Exception e) {
						strErrMsg = "Unable to validate user / password in database";
						System.out.println(e);
					}



				}
				if(request.getParameter("button").equals("Logout")){
					session = request.getSession(false); 
					session.removeAttribute("userName");
					session.invalidate();
					response.sendRedirect("ViewPage?qid=" + reportID);

				}

				if(request.getParameter("button").equals("Not A Member?")){
					response.sendRedirect("default.jsp");
					
				}
				if(request.getParameter("button").equals("Up")){


					int localUserID=-1;
					localUserID=msAccess.getReportOwner(reportID);
					User owner = new User();
					owner = msAccess2.getUser(localUserID);

					if(!(userID.equals(localUserID)))
					{
						if(!(msAccess.IsReportVotedByUserIdAndReportId(userID, reportID)))
						{
							msAccess.insertReportRate(userID, reportID);
							rate = report.getRate()+1;
							msAccess.updateRate(rate, reportID);

							score = owner.getScore();
							wrongReport = owner.getNo_wrong_reports();
							reportRate = owner.getSum_report_rates();

							//means correct report
							if(rate == 5){
								score++;
							}
							msAccess2.updateUser(localUserID, score, wrongReport, reportRate+1);
						}
						else
						{
							request.setAttribute("invalid", true);
						}
					}
					else
					{
						request.setAttribute("owninvalid", true);
					}

					report = msAccess.viewReport(reportID);
				}
				if(request.getParameter("button").equals("Down")){

					int localUserID=-1;
					localUserID=msAccess.getReportOwner(reportID);
					User owner = new User();
					owner = msAccess2.getUser(localUserID);

					if(!(userID.equals(localUserID)))
					{
						if(!(msAccess.IsReportVotedByUserIdAndReportId(userID, reportID)))
						{
							msAccess.insertReportRate(userID, reportID);
							rate = report.getRate()-1;
							msAccess.updateRate(rate, reportID);

							score = owner.getScore();
							wrongReport = owner.getNo_wrong_reports();
							reportRate = owner.getSum_report_rates();

							//means incorrect report
							if(rate == -5){
								wrongReport++;
								score--;

								if(wrongReport==5){
									msAccess2.banUser(localUserID);
								}
								else{
									String mailBody= "Your report '"+report.getReportName()+
											"' does not reflect a real situation. If you keep writing wrong reports, you will be banned of the system." +
											"We believe you will be more careful next time. Thank you for using our system.";
									msAccess.sendMail(owner.getEmail(), "Wrong Report!!", mailBody);
								}
							}

							msAccess2.updateUser(localUserID, score, wrongReport, reportRate-1);
						}
						else
						{
							request.setAttribute("invalid", true);
						}
					}
					else
					{
						request.setAttribute("owninvalid", true);
					}

					report = msAccess.viewReport(reportID);
				}
				if(request.getParameter("button").equals("Subscribe!")){
					if(msAccess.subscriptionExist(userID, reportID)){
						msAccess.changeSubscriptionStatus(true, reportID, userID); 
					}
					else{
						Subscription subs = new Subscription();
						subs.setReportId(reportID);
						subs.setUserId(userID);
						subs.setStatus(true);
						msAccess.addSubscription(subs); 
					}
				}
				if(request.getParameter("button").equals("Unsubscribe!")){
					msAccess.changeSubscriptionStatus(false, reportID, userID);                     
				}
				if(request.getParameter("button").equals("Submit Changes")){
					//change in status
					if(request.getParameter("status")!=null){
						status = request.getParameter("status");
						statusNo = msAccess.getStatus(status);
						msAccess.updateStatus(statusNo, reportID);

						if(status.equals("Fixed")){
							if(msAccess.subscriptionExistonReport(reportID)){
								List<String> mails = new ArrayList<String>();
								mails=  msAccess.getMailsofUsers(reportID);
								String mailBody = "Your subscribed violation '"+report.getReportName()+"' has been fixed. You can visit our website to learn about updates.";
								String mailSubject = "Violation Fixed";
								msAccess.sendMails(mails,mailSubject,mailBody);
							}                                                       
						}
					}
					//adding new comments
					comments = request.getParameter("Comments");                    
					if(!comments.equals("")){
						comment.setReportId(reportID);
						comment.setText(comments);
						comment.setUserId(userID);
						msAccess.addComment(comment);

						request.setAttribute("comment", true);
						List<Comment> commentList2 = msAccess.getComments(reportID);
						request.setAttribute("comments", commentList2);
					}

					//adding description if not existing

				

					if(report.getDescription().equals("")){

						description = request.getParameter("reportDescription");
						System.out.println(description);
						if(!description.equals("")){
							System.out.println("not null");
							msAccess.updateDescription(description,reportID);
						}
					}
					/*      //update image num
                            if(imageNum!=tempImageNum){
                                    msAccess.updateImageNum(imageNum,reportID);
                                    if(imageFileItem!=null){
                                                    imageFileItem.write(new File(imagePath,reportID+"_"+imageNum +"."+getFileExtension(imageFileItem)));
                                            }
                            }*/
					//adding new tags
					newTags = request.getParameter("tags");
					if(!newTags.equals("")){
						String[] tag = splitTags(newTags);
						msAccess.addTags(reportID,tag);         
						List<String> tagsShow2 = msAccess.getTagsInReport(reportID);
						request.setAttribute("tagsShow", tagsShow2);
					}

					report = msAccess.viewReport(reportID);
					request.setAttribute("status", msAccess.getStatusName(report.getStatus()));
				}
				request.setAttribute("report", report);
				subscriptionStatus = msAccess.getSubscriptionStatus(userID,reportID);
				request.setAttribute("subsStatus", subscriptionStatus);
				request.getRequestDispatcher("/viewReport.jsp?qid=" + reportID).forward(request, response);
			}
			else{
				request.getRequestDispatcher("/viewReport.jsp?qid=" + reportID).forward(request, response);
			}
		}
		catch (Exception e) {
			System.out.println(e);
			System.out.println("hata2");
		}

	}

	public String getFileExtension(FileItem fi){
		String fileName = fi.getName();
		int dotposition= fileName.lastIndexOf(".");
		return fileName.substring(dotposition + 1, fileName.length()); 
	}

	public String[] splitTags(String tag){
		String[] tags=tag.split(",");
		return tags;
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request,response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		processRequest(request,response);

	}

}